//
//  MKUITableViewModel.m
//  MKUI
//
//  Created by sushangjin on 14-4-3.
//  Copyright (c) 2014年 sushangjin.com. All rights reserved.
//

#import "MKUITableViewModel.h"
#import "UIScrollView+MKUI.h"
#import "UITableView+MKUI.h"
#import <objc/runtime.h>
#import "NSArray+MKUI.h"
@implementation MKUITableViewModel
- (void)dealloc{
	
}
- (MKUITableViewModel *)init{
	if(self=[super init]){
		self.defaultSectionIndexTitle = MKUITableViewDefaultSectionIndexTitle;
        self.reuseCell = YES;
	}
	return self;
}
- (id)copyWithZone:(NSZone *)zone{
    MKUITableViewModel *obj = [super copyWithZone:zone];
    obj->_defaultIndexTitleSectionModel = self->_defaultIndexTitleSectionModel;
    obj.forwardDataSource = self.forwardDataSource;
    obj.forwardDelegate = self.forwardDelegate;
    obj.tableView= self.tableView;
    obj.showSectionIndexTitle = self.showSectionIndexTitle;
    obj.defaultSectionIndexTitle = self.defaultSectionIndexTitle;
    obj.editing = self.isEditing;
    obj.reuseCell = self.reuseCell;
    obj.emptyBackgroundViewClass = self.emptyBackgroundViewClass;
    obj.emptyBackgroundView = self.emptyBackgroundView;
    obj.whenReloadBackgroundView = [self.whenReloadBackgroundView copy];
    obj.hiddenSectionHeadView = self.hiddenSectionHeadView;
    obj.hiddenSectionFootView = self.hiddenSectionFootView;
    return obj;
}
- (id)initWithTableView:(UITableView *)tableView{
	if (self=[self init]) {
		[self setTableViewDataSourceAndDelegate:tableView];
	}
	return self;
}
- (MKCollectionSectionModel *)createEmptySectionModel{
	MKUITableViewSectionModel *section = [[MKUITableViewSectionModel alloc] init];
	return section;
}
- (void)addCellModel:(MKCollectionCellModel *)cellModel{
	if(!cellModel)return;
	MKUITableViewSectionModel *section = (MKUITableViewSectionModel *)[self.sectionModels lastObject];
	if(!section){
		section = (MKUITableViewSectionModel *)[self createEmptySectionModel];
		[self addSectionModel:section];
	}
	[section addCellModel:cellModel];
}
- (__kindof MKUITableViewCellModel *)cellModelAtIndexPath:(NSIndexPath *)indexpath{
	MKCollectionCellModel *cellModel = [super cellModelAtIndexPath:indexpath];
	if([cellModel isKindOfClass:[MKUITableViewCellModel class]]){
		return (MKUITableViewCellModel *)cellModel;
	}
	return nil;
}
- (__kindof MKUITableViewCellModel *)cellModelForSelectedCellModel{
	MKCollectionCellModel *cellModel = [super cellModelForSelectedCellModel];
	if([cellModel isKindOfClass:[MKUITableViewCellModel class]]){
		return (MKUITableViewCellModel *)cellModel;
	}
	return nil;
}
- (__kindof MKUITableViewSectionModel *)sectionModelAtIndex:(NSInteger)index{
	MKCollectionSectionModel *sectionModel = [super sectionModelAtIndex:index];
	if([sectionModel isKindOfClass:[MKUITableViewSectionModel class]]){
		return (MKUITableViewSectionModel *)sectionModel;
	}
	return nil;
}
- (MKUITableViewSectionModel *)addAutoIndexedCellModel:(MKUITableViewCellModel *)cellModel{
	if(!cellModel){
		return nil;
	}
	BOOL useDefaultIndexTitle = cellModel.indexTitle.length==0;
	NSString *indexTitle = useDefaultIndexTitle?self.defaultSectionIndexTitle:cellModel.indexTitle;
	MKUITableViewSectionModel *sectionModel = useDefaultIndexTitle?_defaultIndexTitleSectionModel:[self sectionModelWithIndexTitle:indexTitle];
	if(!sectionModel){
		sectionModel = (MKUITableViewSectionModel *)[self createEmptySectionModel];
		sectionModel.indexTitle = indexTitle;
		sectionModel.headTitle = indexTitle;
		sectionModel.showHeadView = YES;
		sectionModel.showDefaultHeadView = YES;
		if(useDefaultIndexTitle){
			_defaultIndexTitleSectionModel = sectionModel;
		}
		[self addSectionModel:sectionModel];
	}
	[sectionModel addCellModel:cellModel];
	return sectionModel;
}
/**
 *	根據单元格的索引值,獲取應該被歸類的分组数据
 */
- (MKUITableViewSectionModel *)sectionModelWithIndexTitle:(NSString *)indexTitle{
	MKUITableViewSectionModel *sectionModel;
	for (MKUITableViewSectionModel *m in self.sectionModels) {
		NSString *sectionIndexTitle = m.indexTitle;
		if([sectionIndexTitle isEqual:indexTitle]){
			sectionModel = m;
			break;
		}
	}
	return sectionModel;
}
- (void)sort{
	@MK_WEAKIFY(self);
	[self.mutableSectionModels sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
		@MK_NORMALIZE(self);
		NSString *t1 = [(MKUITableViewSectionModel *)obj1 indexTitle];
		NSString *t2 = [(MKUITableViewSectionModel *)obj2 indexTitle];
		NSComparisonResult r = [t1 compare:t2];
		if(r!=NSOrderedSame){	//保證使用默认的分组索引值位置排序的最底部
			if(obj1==self->_defaultIndexTitleSectionModel){
				r = NSOrderedDescending;
			}else if(obj2==self->_defaultIndexTitleSectionModel){
				r = NSOrderedAscending;
			}
		}
		return r;
	}];
}
- (void)reloadTableViewData{
	[self reloadTableViewDataWithAnimated:NO];
}
- (void)reloadTableViewDataWithAnimated:(BOOL)animated{
    for (MKCollectionSectionModel *section in [self sectionModels]) {
        for (MKUITableViewCellModel *cm in [section cellModels]) {
            cm.needReloadCell = YES;
        }
    }
	[self.tableView reloadData];//reladData时,tableView会清掉旧的行选中状态
	if(self.allowsSelection){
		@MK_WEAKIFY(self);
		dispatch_async(dispatch_get_main_queue(), ^{
			@MK_NORMALIZEANDNOTNIL(self);
			if(self.allowsMultipleSelection){
				NSArray *indexpaths = [self indexPathsForSelectedCellModels];
				for (NSIndexPath *indexpath in indexpaths) {
					[self.tableView selectRowAtIndexPath:indexpath animated:animated scrollPosition:UITableViewScrollPositionNone];
				}
			}else{
				NSIndexPath *indexpath = [self indexPathForSelectedCellModel];
				[self.tableView selectRowAtIndexPath:indexpath animated:animated scrollPosition:UITableViewScrollPositionNone];
			}
		});
	}
	[self reloadTableViewBackgroundView];
}
- (void)addCellModel:(MKUITableViewCellModel *)cellModel animated:(BOOL)animated{
	if(!cellModel)return;
    cellModel.needReloadCell = YES;
	UITableView *tableView = self.tableView;
    MKCollectionSectionModel *sm = [self.sectionModels lastObject];
    BOOL needAddSection = sm==nil;
    if(needAddSection){
        sm = (MKUITableViewSectionModel *)[self createEmptySectionModel];
        [self addSectionModel:sm];
    }
	[self addCellModel:cellModel];
	NSIndexPath *indexpath = [NSIndexPath indexPathForItem:[sm numberOfCells]-1 inSection:self.sectionModels.count-1];
    [tableView mk_performBatchUpdates:^{
        if(needAddSection){//添加section
            [tableView insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:animated?UITableViewRowAnimationAutomatic:UITableViewRowAnimationNone];
        }
        [tableView insertRowsAtIndexPaths:@[indexpath] withRowAnimation:animated?UITableViewRowAnimationAutomatic:UITableViewRowAnimationNone];
    } completion:nil];
    [self reloadTableViewBackgroundView];
}
- (void)insertCellModel:(MKUITableViewCellModel *)cellModel atIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated{
	if(!cellModel||!indexPath)return;
    cellModel.needReloadCell = YES;
	UITableView *tableView = self.tableView;
	MKCollectionSectionModel *sectionModel = [self sectionModelAtIndex:indexPath.section];
    BOOL needAddSection = sectionModel==nil;
    if(needAddSection){
        sectionModel = [self createEmptySectionModel];
        [self insertSectionModel:sectionModel atIndex:indexPath.section];
    }
    [sectionModel insertCellModel:cellModel atIndex:indexPath.row];
    [tableView mk_performBatchUpdates:^{
        if(needAddSection){
            [tableView insertSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:animated?UITableViewRowAnimationAutomatic:UITableViewRowAnimationNone];
        }
        [tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:animated?UITableViewRowAnimationAutomatic:UITableViewRowAnimationNone];
    } completion:nil];
	[self reloadTableViewBackgroundView];
}
- (void)insertCellModel:(MKUITableViewCellModel *)cellModel afterIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated{
	if(!cellModel)return;
	[self insertCellModels:@[cellModel] afterIndexPath:indexPath animated:animated];
}
- (void)insertCellModels:(NSArray *)cellModels afterIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated{
	if(cellModels.count==0||indexPath==nil)return;
	UITableView *tableView = self.tableView;
    for (MKUITableViewCellModel *cm in cellModels) {
        cm.needReloadCell = YES;
    }
    MKCollectionSectionModel *sectionModel = [self sectionModelAtIndex:indexPath.section];
    BOOL needAddSection = sectionModel==nil;
    if(needAddSection){
        sectionModel = [self createEmptySectionModel];
        [self insertSectionModel:sectionModel atIndex:indexPath.section];
    }
	[self insertCellModels:cellModels afterIndexPath:indexPath];
	NSMutableArray *indexPaths = [[NSMutableArray alloc] initWithCapacity:cellModels.count];
	for (int i=0; i<cellModels.count; i++) {
		NSIndexPath *addIndexpath = [NSIndexPath indexPathForRow:indexPath.row+1+i inSection:indexPath.section];
		[indexPaths addObject:addIndexpath];
	}
    [tableView mk_performBatchUpdates:^{
        if(needAddSection){
            [tableView insertSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:animated?UITableViewRowAnimationAutomatic:UITableViewRowAnimationNone];
        }
        [tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:animated?UITableViewRowAnimationAutomatic:UITableViewRowAnimationNone];
    } completion:nil];
	[self reloadTableViewBackgroundView];
}
- (void)insertCellModel:(MKUITableViewCellModel *)cellModel beforeIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated{
	if(!cellModel)return;
	[self insertCellModels:@[cellModel] beforeIndexPath:indexPath animated:animated];
}
- (void)insertCellModels:(NSArray *)cellModels beforeIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated{
	if(cellModels.count==0||indexPath==nil)return;
    for (MKUITableViewCellModel *cm in cellModels) {
        cm.needReloadCell = YES;
    }
	UITableView *tableView = self.tableView;
    MKCollectionSectionModel *sectionModel = [self sectionModelAtIndex:indexPath.section];
    BOOL needAddSection = sectionModel==nil;
    if(needAddSection){
        sectionModel = [self createEmptySectionModel];
        [self addSectionModel:sectionModel];
    }
    
	[self insertCellModels:cellModels beforeIndexPath:indexPath];
	NSMutableArray *indexPaths = [[NSMutableArray alloc] initWithCapacity:cellModels.count];
	for (int i=0; i<cellModels.count; i++) {
		NSIndexPath *addIndexpath = [NSIndexPath indexPathForRow:indexPath.row+i inSection:indexPath.section];
		[indexPaths addObject:addIndexpath];
	}
    [tableView mk_performBatchUpdates:^{
        if(needAddSection){
            [tableView insertSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:animated?UITableViewRowAnimationAutomatic:UITableViewRowAnimationNone];
        }
        [tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:animated?UITableViewRowAnimationAutomatic:UITableViewRowAnimationNone];
        [self reloadTableViewBackgroundView];
    } completion:^(BOOL finished) {
        
    }];
}
- (void)insertCellModelsToBottom:(NSArray<MKUITableViewCellModel *> *)cellModels scrollToBottom:(BOOL)scrollToBottom{
	if(cellModels.count==0)return;
    NSIndexPath *indexpath = nil;
	MKUITableViewSectionModel *sm = (MKUITableViewSectionModel *)[[self sectionModels] lastObject];
    BOOL needAddSection = sm==nil;
	if(needAddSection){
        indexpath = [NSIndexPath indexPathForRow:0 inSection:0];
    }else{
        indexpath = [NSIndexPath indexPathForRow:sm.numberOfCells inSection:self.numberOfSections-1];
    }
    [self insertCellModels:cellModels afterIndexPath:indexpath animated:YES];
    
	//移动到底部
	if(scrollToBottom){
        [self.tableView mk_scrollToBottomCellWithAnimated:YES];
	}
}
- (void)insertCellModelsToTop:(NSArray<MKUITableViewCellModel *> *)cellModels keepContentOffset:(BOOL)keepContentOffset{
	if(cellModels.count==0)return;
    
    BOOL isEmpty = self.numberOfCells==0;//插入之前是否为空
    NSIndexPath *firstIndexpath = [NSIndexPath indexPathForRow:0 inSection:0];
    UITableViewCell *firstCell = !isEmpty?[self.tableView cellForRowAtIndexPath:firstIndexpath]:nil;
    CGRect f1 = firstCell.frame;
    CGPoint offset = self.tableView.contentOffset;
    
    [self insertCellModels:cellModels beforeIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO];
    if(!keepContentOffset)return;
    if(isEmpty){//滚动到底部
        [self.tableView mk_scrollToBottomCellWithAnimated:NO];
    }else{
        NSIndexPath *resumIndexpath = [NSIndexPath indexPathForRow:cellModels.count inSection:0];
        [self.tableView scrollToRowAtIndexPath:resumIndexpath atScrollPosition:(UITableViewScrollPositionTop) animated:NO];
        UITableViewCell *cell2 = [self.tableView cellForRowAtIndexPath:resumIndexpath];
        if(!cell2){
            [self.tableView mk_scrollToBottomCellWithAnimated:NO];
            return;
        }
        CGRect f2 = cell2.frame;
        CGPoint resumOffset = offset;
        resumOffset.y = offset.y+f2.origin.y-f1.origin.y;
        [self.tableView setContentOffset:resumOffset animated:NO];
    }
}

- (void)removeCellModel:(MKUITableViewCellModel *)cellModel animated:(BOOL)animated{
	if(!cellModel)return;
	NSIndexPath *indexpath = [self indexPathOfCellModel:cellModel];
    if(!indexpath)return;
    cellModel.needReloadCell = YES;
    [self removeCellModelAtIndexPath:indexpath];
    UITableView *tableView = self.tableView;
    [tableView mk_performBatchUpdates:^{
        [tableView deleteRowsAtIndexPaths:@[indexpath] withRowAnimation:animated?UITableViewRowAnimationAutomatic:UITableViewRowAnimationNone];
    } completion:nil];
    [self reloadTableViewBackgroundView];
}
- (void)removeCellModels:(NSArray *)cellModels animated:(BOOL)animated{
	if(cellModels.count==0)return;
	NSArray *indexpaths = [self indexPathsOfCellModels:cellModels];
	[self removeCellModelsAtIndexPaths:indexpaths animated:animated];
}
- (void)removeCellModelsAtIndexPaths:(NSArray *)indexpaths animated:(BOOL)animated{
	if(indexpaths.count==0)return;
	[self removeCellModelsAtIndexPaths:indexpaths];
	UITableView *tableView = self.tableView;
    [tableView mk_performBatchUpdates:^{
        [tableView deleteRowsAtIndexPaths:indexpaths withRowAnimation:animated?UITableViewRowAnimationAutomatic:UITableViewRowAnimationNone];
    } completion:nil];
	[self reloadTableViewBackgroundView];
}
- (void)insertSectionModel:(MKUITableViewSectionModel *)sectionModel atIndex:(NSInteger)index animated:(BOOL)animated{
	if(!sectionModel)return;
    for (MKUITableViewCellModel *cm in [sectionModel cellModels]) {
        cm.needReloadCell = YES;
    }
	UITableView *tableView = self.tableView;
	[self insertSectionModel:sectionModel atIndex:index];
	
	NSIndexSet *set = [NSIndexSet indexSetWithIndex:index];
	NSInteger count = sectionModel.numberOfCells;
	NSMutableArray<NSIndexPath *> *indexpaths = [[NSMutableArray alloc] initWithCapacity:count];
	for (int i=0; i<count; i++) {
		NSIndexPath *indexpath = [NSIndexPath indexPathForRow:index inSection:index];
		[indexpaths addObject:indexpath];
	}
	
    [tableView mk_performBatchUpdates:^{
        [tableView insertSections:set withRowAnimation:animated?UITableViewRowAnimationAutomatic:UITableViewRowAnimationNone];
        [tableView insertRowsAtIndexPaths:indexpaths withRowAnimation:animated?UITableViewRowAnimationAutomatic:UITableViewRowAnimationNone];
    } completion:nil];
}
- (void)removeSectionModel:(MKUITableViewSectionModel *)sectionModel animated:(BOOL)animated{
	UITableView *tableView = self.tableView;
	NSInteger index = sectionModel.indexInModel;
	[self removeSectionModel:sectionModel];
	
	NSIndexSet *set = [NSIndexSet indexSetWithIndex:index];
	NSInteger count = sectionModel.numberOfCells;
	NSMutableArray<NSIndexPath *> *indexpaths = [[NSMutableArray alloc] initWithCapacity:count];
	for (int i=0; i<count; i++) {
		NSIndexPath *indexpath = [NSIndexPath indexPathForRow:index inSection:index];
		[indexpaths addObject:indexpath];
	}
	
    [tableView mk_performBatchUpdates:^{
        [tableView deleteSections:set withRowAnimation:animated?UITableViewRowAnimationAutomatic:UITableViewRowAnimationNone];
        [tableView deleteRowsAtIndexPaths:indexpaths withRowAnimation:animated?UITableViewRowAnimationAutomatic:UITableViewRowAnimationNone];
    } completion:nil];
}
- (void)deselectAllCellModelsWithAnimated:(BOOL)animated{
    [self deselectAllCellModels];
    for (NSIndexPath *p in self.tableView.indexPathsForSelectedRows) {
        [self.tableView deselectRowAtIndexPath:p animated:animated];
    }
}
- (void)deselectCellModels:(NSArray<MKCollectionCellModel *> *)cellModels animated:(BOOL)animated{
    [super deselectCellModels:cellModels];
    for (MKUITableViewCellModel *cm in cellModels) {
        [self.tableView deselectRowAtIndexPath:cm.indexPathInModel animated:animated];
    }
}
- (void)selectAllCellModelsWithAnimated:(BOOL)animated{
    [self selectAllCellModels];
    for (int i=0; i<self.numberOfSections; i++) {
        MKCollectionSectionModel *sm = [self sectionModelAtIndex:i];
        for (int j=0; j<sm.numberOfCells; j++) {
            [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:j inSection:i] animated:animated scrollPosition:(UITableViewScrollPositionNone)];
        }
    }
    [self selectCellModels:self.allCellModels animated:animated];
}
- (void)selectCellModels:(NSArray<MKUITableViewCellModel *> *)cellModels animated:(BOOL)animated{
    [super selectCellModels:cellModels];
    for (MKUITableViewCellModel *cm in cellModels) {
        [self.tableView selectRowAtIndexPath:cm.indexPathInModel animated:animated scrollPosition:(UITableViewScrollPositionNone)];
    }
}
- (void)setCellModel:(MKUITableViewCellModel *)cellModel selected:(BOOL)selected animated:(BOOL)animated{
    CGPoint offset = self.tableView.contentOffset;
    if(selected){
        [self selectCellModel:cellModel];
        [self.tableView selectRowAtIndexPath:cellModel.indexPathInModel animated:animated scrollPosition:(UITableViewScrollPositionTop)];
    }else{
        [self deselectCellModel:cellModel];
        [self.tableView deselectRowAtIndexPath:cellModel.indexPathInModel animated:animated];
    }
    if(!animated){//防止因为设置了选中indexpath，导致的画面滚动
        self.tableView.contentOffset = offset;
    }
}
#pragma mark - forward
- (MKUITableViewModel *)forwardDataSourceTo:(NSObject<UITableViewDataSource> *)dataSource{
	self.forwardDataSource = dataSource;
	return self;
}
- (MKUITableViewModel *)forwardDelegateTo:(NSObject<UITableViewDelegate> *)delegate{
	self.forwardDelegate = delegate;
	return self;
}
- (void)setTableViewDataSourceAndDelegate:(UITableView *)tableView{
	self.tableView = tableView;
	tableView.dataSource = self;
	tableView.delegate = self;
}
- (void)setForwardDelegate:(id<UITableViewDelegate>)forwardDelegate{
	_forwardDelegate = forwardDelegate;
	if(self.tableView.delegate==self){
		self.tableView.delegate = nil;
		self.tableView.delegate = self;//重新赋值一次,使得scrollview重新判断scrollViewDidScroll:方法的有无
	}
}
- (void)setHiddenSectionHeadView:(BOOL)hiddenSectionHeadView{
    if(_hiddenSectionHeadView!=hiddenSectionHeadView){
        _hiddenSectionHeadView = hiddenSectionHeadView;
        [self __resetTableViewDelegateDataSource];
    }
}
- (void)setHiddenSectionFootView:(BOOL)hiddenSectionFootView{
    if(_hiddenSectionFootView!=hiddenSectionFootView){
        _hiddenSectionFootView = hiddenSectionFootView;
        [self __resetTableViewDelegateDataSource];
    }
}
- (void)hideSectionHeadFootView{
    BOOL change = !_hiddenSectionHeadView||!_hiddenSectionHeadView;
    _hiddenSectionHeadView = YES;
    _hiddenSectionFootView = YES;
    if(change){
        [self __resetTableViewDelegateDataSource];
    }
}
- (void)__resetTableViewDelegateDataSource{
    if(self.tableView.delegate==self){
        self.tableView.delegate = nil;
        self.tableView.delegate = self;//重新赋值一次,使得scrollview重新判断scrollViewDidScroll:方法的有无
    }
    if(self.tableView.dataSource==self){
        self.tableView.dataSource = nil;
        self.tableView.dataSource = self;
    }
}
#pragma mark - empty background
- (UIView *)createEmptyBackgroundView{
	Class c = self.emptyBackgroundViewClass;
	UIView *view;
	if(c){
		view = [[c alloc] init];
	}
	return view;
}
- (void)reloadTableViewBackgroundView{
	if(!self.emptyBackgroundViewClass&&!self.emptyBackgroundView)return;
	if(self.numberOfCells==0){
		if(!self.emptyBackgroundView){
			self.emptyBackgroundView = [self createEmptyBackgroundView];
		}
		self.tableView.backgroundView = self.emptyBackgroundView;
	}else{
		self.tableView.backgroundView = nil;
	}
	if(self.whenReloadBackgroundView) {
		self.whenReloadBackgroundView(self);
	}
}
#pragma mark - Forward Invocations
/**
 *根據指定的Selector返回該類支持的方法簽名,一般用於prototol或者消息轉發forwardInvocation:中NSInvocation參數的methodSignature屬性
 注:系統調用- (void)forwardInvocation:(NSInvocation *)invocation方法前,會先調用此方法獲取NSMethodSignature,然後生成方法所需要的NSInvocation
 */
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
	NSMethodSignature *signature = [super methodSignatureForSelector:selector];
	if (signature == nil) {
		id delegate = self.forwardDelegate;
		if ([delegate respondsToSelector:selector]) {
			signature = [delegate methodSignatureForSelector:selector];
		}else{
			delegate = self.forwardDataSource;
			if ([delegate respondsToSelector:selector]) {
				signature = [delegate methodSignatureForSelector:selector];
			}
		}
	}
	return signature;
}
- (BOOL)conformsToProtocol:(Protocol *)aProtocol{
    BOOL conforms = NO;
    if([super conformsToProtocol:aProtocol]){
        conforms = YES;
    }else{
        if([self.forwardDelegate conformsToProtocol:aProtocol]){
            conforms = YES;
        }else if([self.forwardDataSource conformsToProtocol:aProtocol]){
            conforms = YES;
        }
    }
    return conforms;
}
- (BOOL)respondsToSelector:(SEL)selector {
    BOOL responds = NO;
	if ([super respondsToSelector:selector]) {
        responds = YES;
	} else {
		if([self.forwardDelegate respondsToSelector:selector]){
            responds = YES;
		}else if([self.forwardDataSource respondsToSelector:selector]){
            responds = YES;
		}
	}
    if(!responds && !self.hiddenSectionHeadView){
        if(selector==@selector(tableView:heightForHeaderInSection:)){
            responds = YES;
        }else if(selector==@selector(tableView:titleForHeaderInSection:)){
            responds = YES;
        }else if(selector==@selector(tableView:viewForHeaderInSection:)){
            responds = YES;
        }
    }
    if(!responds && !self.hiddenSectionFootView){
        if(selector==@selector(tableView:heightForFooterInSection:)){
            responds = YES;
        }else if(selector==@selector(tableView:titleForFooterInSection:)){
            responds = YES;
        }else if(selector==@selector(tableView:viewForFooterInSection:)){
            responds = YES;
        }
    }
	return responds;
}
/**
 *对调用未定义的方法进行消息重定向
 */
- (void)forwardInvocation:(NSInvocation *)invocation {
	BOOL didForward = NO;
	id delegate = self.forwardDelegate;
	if ([delegate respondsToSelector:invocation.selector]) {
		[invocation invokeWithTarget:delegate];
		didForward = YES;
	}
	if(!didForward){
		delegate = self.forwardDataSource;
		if ([delegate respondsToSelector:invocation.selector]) {
			[invocation invokeWithTarget:delegate];
			didForward = YES;
		}
	}
	if (!didForward) {
        BOOL responds = NO;
        if(!self.hiddenSectionHeadView){
            //当要显示section的head、foot时，使用重定向到__tableView:xx:相应方法
            SEL selector = invocation.selector;
            if(selector==@selector(tableView:heightForHeaderInSection:)){
                invocation.selector = @selector(__tableView:heightForHeaderInSection:);
                responds = YES;
            }else if(selector==@selector(tableView:titleForHeaderInSection:)){
                invocation.selector = @selector(__tableView:titleForHeaderInSection:);
                responds = YES;
            }else if(selector==@selector(tableView:viewForHeaderInSection:)){
                invocation.selector = @selector(__tableView:viewForHeaderInSection:);
                responds = YES;
            }
        }
        
        if(!self.hiddenSectionFootView){
            //当要显示section的head、foot时，使用重定向到__tableView:xx:相应方法
            SEL selector = invocation.selector;
            if(selector==@selector(tableView:heightForFooterInSection:)){
                invocation.selector = @selector(__tableView:heightForFooterInSection:);
                responds = YES;
            }else if(selector==@selector(tableView:titleForFooterInSection:)){
                invocation.selector = @selector(__tableView:titleForFooterInSection:);
                responds = YES;
            }else if(selector==@selector(tableView:viewForFooterInSection:)){
                invocation.selector = @selector(__tableView:viewForFooterInSection:);
                responds = YES;
            }
        }
        if(responds){
            [invocation invokeWithTarget:self];
        }else{
            [super forwardInvocation:invocation];
        }
	}
}
- (void)doesNotRecognizeSelector:(SEL)aSelector{
    [super doesNotRecognizeSelector:aSelector];
}
#pragma mark - delegate:UITableViewDataSource,UITableViewDelegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
	self.tableView = tableView;
	MKUITableViewSectionModel *sectionModel = [self sectionModelAtIndex:section];
	NSInteger number = [sectionModel numberOfCells];
	return number;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
	MKUITableViewCellModel *cellModel = [self cellModelAtIndexPath:indexPath];
    UITableViewCell<MKUITableViewCellProtocol> *cell = nil;
    Class cellClass = cellModel.cellClass;
    if(cellClass&&cell&&![cell isKindOfClass:cellClass]){
        cell = nil;
    }
    if(!cell){
        NSString *identity = self.reuseCell?cellModel.reuseIdentity:[NSString stringWithFormat:@"%@_%p",cellModel.reuseIdentity,cellModel];
        //当取消重用时，identity将添加上cellModel的内存地址
        cell = [tableView dequeueReusableCellWithIdentifier:identity];
        if(!cell){
            if(!cellClass){
                cellClass = [UITableViewCell class];
            }
            cell = [[cellClass alloc] initWithStyle:cellModel.cellStyle reuseIdentifier:identity];
        }
    }
	[cellModel displayCell:cell];
	return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
	NSInteger sections = [self numberOfSections];
	return sections;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
	BOOL edit = NO;
	MKUITableViewCellModel *cellModel = [self cellModelAtIndexPath:indexPath];
	edit = cellModel.canEdit;
	return edit;
}
- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{
    if([self.forwardDelegate respondsToSelector:_cmd]){
        return [self.forwardDelegate tableView:tableView editActionsForRowAtIndexPath:indexPath];
    }
    MKUITableViewCellModel *cellModel = [self cellModelAtIndexPath:indexPath];
    return cellModel.editActions;
}
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos){
    if([self.forwardDelegate respondsToSelector:_cmd]){
        return [self.forwardDelegate tableView:tableView leadingSwipeActionsConfigurationForRowAtIndexPath:indexPath];
    }
    MKUITableViewCellModel *cellModel = [self cellModelAtIndexPath:indexPath];
    return [cellModel swipeActionsConfigurationWithIndexPath:indexPath leading:YES];
}
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos){
    //注：实现了trailingSwipeActionsConfigurationForRowAtIndexPath/leadingSwipeActionsConfigurationForRowAtIndexPath方法，要ios11上，就不会再去调用editActionsForRowAtIndexPath方法了
    if([self.forwardDelegate respondsToSelector:_cmd]){
        return [self.forwardDelegate tableView:tableView trailingSwipeActionsConfigurationForRowAtIndexPath:indexPath];
    }
    MKUITableViewCellModel *cellModel = [self cellModelAtIndexPath:indexPath];
    return [cellModel swipeActionsConfigurationWithIndexPath:indexPath leading:NO];
}

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath{
	BOOL move = NO;
	MKUITableViewCellModel *cellModel = [self cellModelAtIndexPath:indexPath];
	move = cellModel.canMove;
	return move;
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
	MKUITableViewCellModel *cellModel = [self cellModelAtIndexPath:indexPath];
	if(cellModel.whenClickAccessory){
		cellModel.whenClickAccessory(cellModel);
	}
}
- (NSArray*)_sectionIndexTitlesForTableView:(UITableView *)tableView{
	NSMutableArray *sectionIndexTitles = nil;
	if(self.showSectionIndexTitle){
		sectionIndexTitles = [[NSMutableArray alloc] init];
		for (MKUITableViewSectionModel *sectionModel in self.sectionModels) {
			NSString *title = sectionModel.indexTitle?:self.defaultSectionIndexTitle;
			if(title){
				[sectionIndexTitles addObject:@{@"title":title,@"model":sectionModel}];
			}
		}
	}
	return sectionIndexTitles;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{ // return list of section titles to display in section index view (e.g. "ABCD...Z#")
	NSMutableArray *sectionIndexTitles = nil;
	if(self.showSectionIndexTitle){
		sectionIndexTitles = [[NSMutableArray alloc] init];
		NSArray *map = [self _sectionIndexTitlesForTableView:tableView];
		for (NSDictionary* info in map) {
			NSString *title = info[@"title"];
			[sectionIndexTitles addObject:title];
		}
	}
	return sectionIndexTitles;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index{// tell table which section corresponds to section title/index (e.g. "B",1))
	NSInteger sectionIndex = NSNotFound;
	if(self.showSectionIndexTitle){
		NSArray *map = [self _sectionIndexTitlesForTableView:tableView];
		NSDictionary *info = [map objectAtIndex:index];
		MKUITableViewSectionModel *sectionModel = info[@"model"];
		sectionIndex = [self indexOfSectionModel:sectionModel];
	}
	return sectionIndex;
}
// Data manipulation - insert and delete support
// After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{//使用默认的左侧按钮时，才会被触发
	if(editingStyle==UITableViewCellEditingStyleDelete){
		MKUITableViewCellModel *cellModel = nil;
		MKUITableViewSectionModel *sectionModel = [self sectionModelAtIndex:indexPath.section];
		cellModel = [sectionModel cellModelAtIndex:indexPath.row];
		if(cellModel.whenDelete){
			cellModel.whenDelete(cellModel);
		}
	}
	if([self.forwardDataSource respondsToSelector:_cmd]){
		[self.forwardDataSource tableView:tableView commitEditingStyle:editingStyle forRowAtIndexPath:indexPath];
	}
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
	MKUITableViewCellModel *srcTablecellModel = [self cellModelAtIndexPath:sourceIndexPath];
	MKUITableViewCellModel *dstTablecellModel = [self cellModelAtIndexPath:destinationIndexPath];
	BOOL handed = NO;
	MKUITableViewCellModelBlockM handler = srcTablecellModel.whenMove?:dstTablecellModel.whenMove;
	if(handler){
		handler(srcTablecellModel,dstTablecellModel);
		handed = YES;
	}
	if([self.forwardDataSource respondsToSelector:_cmd]){
		[self.forwardDataSource tableView:tableView moveRowAtIndexPath:sourceIndexPath toIndexPath:destinationIndexPath];
		handed = YES;
	}
	if(!handed){
		[self moveCellModelAtIndexPath:sourceIndexPath toIndexPath:destinationIndexPath];
	}
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
	MKUITableViewCellModel *cellModel = [self cellModelAtIndexPath:indexPath];
	Class cellClass = cellModel.cellClass;
	
	CGFloat height = [cellClass heightWithTableView:tableView cellModel:cellModel];
	return height;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
    MKUITableViewCellModel *cellModel = [self cellModelAtIndexPath:indexPath];
    Class cellClass = cellModel.cellClass;
    CGFloat height = [cellClass estimatedHeightWithTableView:tableView cellModel:cellModel];
    return height;
}
- (CGFloat)__tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
	CGFloat height = 0;
	MKUITableViewSectionModel *sectionModel = [self sectionModelAtIndex:section];
	if (sectionModel.showHeadView) {
		if(sectionModel.showDefaultHeadView){
			height = sectionModel.headViewHeight;
            if(height==0){
                height = UITableViewAutomaticDimension;
            }
		}else{
			height = [sectionModel.headViewClass heightWithTableView:tableView sectionModel:sectionModel kind:MKUITableViewSectionViewKindOfHead];
		}
	}
	return height;
}
- (CGFloat)__tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
	CGFloat height = 0;
	MKUITableViewSectionModel *sectionModel = [self sectionModelAtIndex:section];
	if(sectionModel.showFootView){
		if(sectionModel.showDefaultFootView){
			height = sectionModel.footViewHeight;
            if(height==0){
                height = UITableViewAutomaticDimension;
            }
		}else{
			height = [sectionModel.footViewClass heightWithTableView:tableView sectionModel:sectionModel kind:MKUITableViewSectionViewKindOfFoot
					  ];
		}
	}
	return height;
}
- (NSString *)__tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
	MKUITableViewSectionModel *sectionModel = [self sectionModelAtIndex:section];
	NSString *title = sectionModel.headTitle;
    if(title.length==0&&sectionModel.showHeadView){
        title = @" ";
        //当显示自定义视图时，如果没有title且height为UITableViewAutomaticDimension，会不显示视图。因此这里手动赋值上空格字符串
    }
	return title;
}
- (NSString *)__tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
	MKUITableViewSectionModel *sectionModel = [self sectionModelAtIndex:section];
	NSString *title = sectionModel.footTitle;
    if(title.length==0&&sectionModel.showFootView){
        title = @" ";
        //当显示自定义视图时，如果没有title且height为UITableViewAutomaticDimension，会不显示视图。因此这里手动赋值上空格字符串
    }
	return title;
}
- (UIView *)__tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
	UIView<MKUITableViewSectionViewProtocol> *view = nil;
	MKUITableViewSectionModel *sectionModel = [self sectionModelAtIndex:section];
	if(!sectionModel.showDefaultHeadView){
		Class c = sectionModel.headViewClass;
		if(c){
			CGRect f = CGRectMake(0, 0, tableView.bounds.size.width, 40);
			CGFloat h = [self tableView:tableView heightForHeaderInSection:section];
            if(h>=0){
                f.size.height = h;
            }
			view = [[c alloc] initWithFrame:f];
			[sectionModel displayHeadView:view];
		}
	}
	return view;
}
- (UIView *)__tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
	UIView<MKUITableViewSectionViewProtocol> *view = nil;
	MKUITableViewSectionModel *sectionModel = [self sectionModelAtIndex:section];
	if(!sectionModel.showDefaultFootView){
		Class c = sectionModel.footViewClass;
		if(c){
			CGRect f = CGRectMake(0, 0, tableView.bounds.size.width, 40);
			CGFloat h = [self tableView:tableView heightForFooterInSection:section];
            if(h>=0){
                f.size.height = h;
            }
			view = [[c alloc] initWithFrame:f];
			[sectionModel displayFootView:view];
		}
	}
	return view;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
	UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
	if(cell
	   &&[cell conformsToProtocol:@protocol(MKUITableViewCellProtocol)]
	   &&[cell respondsToSelector:@selector(tableView:didSelectCell:)]
	   ){
		[cell tableView:tableView didSelectCell:YES];
	}
	MKUITableViewCellModel *cellModel = [self cellModelAtIndexPath:indexPath];
	[self selectCellModel:cellModel];
	if(cellModel.whenSelected){
		cellModel.whenSelected(cellModel,YES);
	}
	if(cellModel.whenClick){
		cellModel.whenClick(cellModel);
	}
	if([self.forwardDelegate respondsToSelector:_cmd]){
		[self.forwardDelegate tableView:tableView didSelectRowAtIndexPath:indexPath];
	}
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
	UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
	if(cell
	   &&[cell conformsToProtocol:@protocol(MKUITableViewCellProtocol)]
	   &&[cell respondsToSelector:@selector(tableView:didSelectCell:)]
	   ){
		[cell tableView:tableView didSelectCell:NO];
	}
	MKUITableViewCellModel *cellModel = [self cellModelAtIndexPath:indexPath];
	[self deselectCellModel:cellModel];
	if(cellModel.whenSelected){
		cellModel.whenSelected(cellModel,NO);
	}
	if(tableView.allowsMultipleSelection){//多选时,deselect代表选中行被点击了
		if(cellModel.whenClick){
			cellModel.whenClick(cellModel);
		}
	}
	if([self.forwardDelegate respondsToSelector:_cmd]){
		[self.forwardDelegate tableView:tableView didDeselectRowAtIndexPath:indexPath];
	}
}

// Display customization

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
    if([cell conformsToProtocol:@protocol(MKUITableViewCellProtocol)] && [cell respondsToSelector:@selector(tableView:willDisplayCellModel:)]){
        MKUITableViewCellModel *cellModel = [self cellModelAtIndexPath:indexPath];
        [(UITableViewCell<MKUITableViewCellProtocol> *)cell tableView:tableView willDisplayCellModel:cellModel];
    }
    if([self.forwardDelegate respondsToSelector:_cmd]){
        [self.forwardDelegate tableView:tableView willDisplayCell:cell forRowAtIndexPath:indexPath];
    }
}
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section API_AVAILABLE(ios(6.0)){
    if([view conformsToProtocol:@protocol(MKUITableViewSectionViewProtocol)] && [view respondsToSelector:@selector(tableView:willDisplaySectionModel:kind:)]){
        MKUITableViewSectionModel *sectionModel = [self sectionModelAtIndex:section];
        [(UIView<MKUITableViewSectionViewProtocol> *)view tableView:tableView willDisplaySectionModel:sectionModel kind:(MKUITableViewSectionViewKindOfHead)];
    }
    if([self.forwardDelegate respondsToSelector:_cmd]){
        [self.forwardDelegate tableView:tableView willDisplayHeaderView:view forSection:section];
    }
}
- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section API_AVAILABLE(ios(6.0)){
    if([view conformsToProtocol:@protocol(MKUITableViewSectionViewProtocol)] && [view respondsToSelector:@selector(tableView:willDisplaySectionModel:kind:)]){
        MKUITableViewSectionModel *sectionModel = [self sectionModelAtIndex:section];
        [(UIView<MKUITableViewSectionViewProtocol> *)view tableView:tableView willDisplaySectionModel:sectionModel kind:(MKUITableViewSectionViewKindOfFoot)];
    }
    if([self.forwardDelegate respondsToSelector:_cmd]){
        [self.forwardDelegate tableView:tableView willDisplayFooterView:view forSection:section];
    }
}
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath API_AVAILABLE(ios(6.0)){
   if([cell conformsToProtocol:@protocol(MKUITableViewCellProtocol)] && [cell respondsToSelector:@selector(tableView:didEndDisplayingCellModel:)]){
        MKUITableViewCellModel *cellModel = [self cellModelAtIndexPath:indexPath];
        [(UITableViewCell<MKUITableViewCellProtocol> *)cell tableView:tableView didEndDisplayingCellModel:cellModel];
    }
    if([self.forwardDelegate respondsToSelector:_cmd]){
        [self.forwardDelegate tableView:tableView didEndDisplayingCell:cell forRowAtIndexPath:indexPath];
    }
}
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section API_AVAILABLE(ios(6.0)){
    if([view conformsToProtocol:@protocol(MKUITableViewSectionViewProtocol)] && [view respondsToSelector:@selector(tableView:didEndDisplayingSectionModel:kind:)]){
        MKUITableViewSectionModel *sectionModel = [self sectionModelAtIndex:section];
        [(UIView<MKUITableViewSectionViewProtocol> *)view tableView:tableView didEndDisplayingSectionModel:sectionModel kind:(MKUITableViewSectionViewKindOfHead)];
    }
    if([self.forwardDelegate respondsToSelector:_cmd]){
        [self.forwardDelegate tableView:tableView didEndDisplayingHeaderView:view forSection:section];
    }
}
- (void)tableView:(UITableView *)tableView didEndDisplayingFooterView:(UIView *)view forSection:(NSInteger)section API_AVAILABLE(ios(6.0)){
    if([view conformsToProtocol:@protocol(MKUITableViewSectionViewProtocol)] && [view respondsToSelector:@selector(tableView:didEndDisplayingSectionModel:kind:)]){
        MKUITableViewSectionModel *sectionModel = [self sectionModelAtIndex:section];
        [(UIView<MKUITableViewSectionViewProtocol> *)view tableView:tableView didEndDisplayingSectionModel:sectionModel kind:(MKUITableViewSectionViewKindOfFoot)];
    }
    if([self.forwardDelegate respondsToSelector:_cmd]){
        [self.forwardDelegate tableView:tableView didEndDisplayingFooterView:view forSection:section];
    }
}
#pragma debug
- (NSString *)description{
	return [NSString stringWithFormat:@"%@:[sectionModels:%@,showSectionIndexTitle:%d,userInfo:%@]",NSStringFromClass(self.class),self.sectionModels,self.showSectionIndexTitle,self.userInfo];
}
@end
